home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / CBGRX103.ZIP / contrib / libgrx / src / pibitblt.c < prev    next >
Text File  |  1993-12-06  |  6KB  |  208 lines

  1. /**
  2.  ** PIBITBLT.C
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "p8514a.h"
  25. #include "memcopy.h"
  26.  
  27. static int blitmixes[] = {
  28.     MIX_REPLACE | FSS_BITBLT,
  29.     MIX_XOR    | FSS_BITBLT,
  30.     MIX_OR    | FSS_BITBLT,
  31.     MIX_AND    | FSS_BITBLT
  32. };
  33.  
  34. static int pc_blitmixes[] = {
  35.     MIX_REPLACE | FSS_PCDATA,
  36.     MIX_XOR    | FSS_PCDATA,
  37.     MIX_OR    | FSS_PCDATA,
  38.     MIX_AND    | FSS_PCDATA
  39. };
  40.  
  41. void _GrPIPixCopy(GC *dst,long daddr,GC *src,long saddr,int w,int h,int op)
  42. {
  43.     pixptr dstp,srcp;
  44.     int doff,soff;
  45.     int oper = C_OPER(op);
  46.  
  47.     if((w <= 0) || (h <= 0)) return;
  48.     _ClrDir();
  49.     if(dst->gc_onscreen) {
  50.         if(src->gc_onscreen) {
  51.         WaitQueue(8);
  52.         outpw(MAJ_AXIS_PCNT,(w - 1));
  53.         outpw(MULTIFUNC_CNTL,((h - 1) | MIN_AXIS_PCNT));
  54.         outpw(FRGD_MIX,blitmixes[oper]);
  55.         if(daddr > saddr) {
  56.             outpw(CUR_X,COORD_X(saddr) + w - 1);
  57.             outpw(CUR_Y,COORD_Y(saddr) + h - 1);
  58.             outpw(DESTX_DIASTP,COORD_X(daddr) + w - 1);
  59.             outpw(DESTY_AXSTP,COORD_Y(daddr) + h - 1);
  60.             outpw(CMD,(CMD_BITBLT | DRAW | PLANAR | WRTDATA));
  61.         }
  62.         else {
  63.             outpw(CUR_X,COORD_X(saddr));
  64.             outpw(CUR_Y,COORD_Y(saddr));
  65.             outpw(DESTX_DIASTP,COORD_X(daddr));
  66.             outpw(DESTY_AXSTP,COORD_Y(daddr));
  67.             outpw(CMD,(CMD_BITBLT | INC_X | INC_Y | DRAW | PLANAR | WRTDATA));
  68.         }
  69.         return;
  70.         }
  71.         WaitQueue(6);
  72.         outpw(CUR_X,COORD_X(daddr));
  73.         outpw(CUR_Y,COORD_Y(daddr));
  74.         outpw(MAJ_AXIS_PCNT,(w - 1));
  75.         outpw(MULTIFUNC_CNTL,((h - 1) | MIN_AXIS_PCNT));
  76.         outpw(FRGD_MIX,pc_blitmixes[oper]);
  77.         srcp = P_ADDRESS(src,saddr);
  78.         soff = src->gc_lineoffset - w;
  79. #ifdef __TURBOC__
  80. #define _HAVE_INLINE_
  81.         if((w | soff | (int)srcp) & 1) {
  82.         outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | DRAW | WRTDATA));
  83.         WaitQueue(8);
  84.         asm cld;
  85.         asm push    ds;
  86.         asm lds        si,srcp;
  87.         asm mov        bx,WORD PTR h;
  88.         asm mov        dx,PIX_TRANS;
  89.           BVLoop:
  90.         asm mov        cx,WORD PTR w;
  91.           BHLoop:
  92.         asm lodsb;
  93.         asm out        dx,ax;
  94.         asm loop    BHLoop;
  95.         asm add        si,WORD PTR soff;
  96.         asm dec        bx;
  97.         asm jne        BVLoop;
  98.         asm pop        ds;
  99.         }
  100.         else {
  101.         w >>= 1;
  102.         outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | _16BIT | BYTSEQ | DRAW | WRTDATA));
  103.         WaitQueue(8);
  104.         asm .286
  105.         asm cld;
  106.         asm push    ds;
  107.         asm lds        si,srcp;
  108.         asm mov        bx,WORD PTR h;
  109.         asm mov        dx,PIX_TRANS;
  110.           WLoop:
  111.         asm mov        cx,WORD PTR w;
  112.         asm rep        outsw;
  113.         asm add        si,WORD PTR soff;
  114.         asm dec        bx;
  115.         asm jne        WLoop;
  116.         asm pop        ds;
  117.         }
  118. #endif
  119. #ifdef __GNUC__
  120. #define _HAVE_INLINE_
  121.         if((w | soff | (int)srcp) & 1) {
  122.         outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | DRAW | WRTDATA));
  123.         WaitQueue(8);
  124.         asm volatile("                                  \n\
  125.             cld                        \n\
  126.             movl    %0,%%esi                \n\
  127.             movl    %1,%%ebx                \n\
  128.             movl    %2,%%edx                \n\
  129.           L_BVLoop:                    \n\
  130.             movl    %3,%%ecx                \n\
  131.           L_BHLoop:                    \n\
  132.             lodsb                    \n\
  133.             outw    %%ax,%%dx                \n\
  134.             loop    L_BHLoop                \n\
  135.             addl    %4,%%esi                \n\
  136.             decl    %%ebx                \n\
  137.             jne        L_BVLoop                  "
  138.             : /* no inputs */
  139.             : "g" (srcp), "g" (h), "g" (PIX_TRANS), "g" (w), "g" (soff)
  140.             : "si", "dx", "cx", "bx", "ax"
  141.         );
  142.         }
  143.         else {
  144.         w >>= 1;
  145.         outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | _16BIT | BYTSEQ | DRAW | WRTDATA));
  146.         WaitQueue(8);
  147.         asm volatile("                                  \n\
  148.             cld                        \n\
  149.             movl    %0,%%esi                \n\
  150.             movl    %1,%%ebx                \n\
  151.             movl    %2,%%edx                \n\
  152.           L_WLoop:                    \n\
  153.             movl    %3,%%ecx                \n\
  154.             rep                        \n\
  155.             outsw                    \n\
  156.             addl    %4,%%esi                \n\
  157.             decl    %%ebx                \n\
  158.             jne        L_WLoop                  "
  159.             : /* no inputs */
  160.             : "g" (srcp), "g" (h), "g" (PIX_TRANS), "g" (w), "g" (soff)
  161.             : "si", "dx", "cx", "bx"
  162.         );
  163.         }
  164. #endif
  165. #ifndef _HAVE_INLINE_
  166.         outpw(CMD,(CMD_RECT | INC_X | INC_Y | PCDATA | DRAW | WRTDATA));
  167.         WaitQueue(8);
  168.         while(--h >= 0) {
  169.         for(doff = w; --doff >= 0; ) outpw(PIX_TRANS,*srcp++);
  170.         srcp += soff;
  171.         }
  172. #endif
  173.         return;
  174.     }
  175.     if(src->gc_onscreen) {
  176.         int command = CMD_RECT | INC_X | INC_Y | PCDATA | DRAW;
  177.         WaitQueue(6);
  178.         outpw(CUR_X,COORD_X(saddr));
  179.         outpw(CUR_Y,COORD_Y(saddr));
  180.         outpw(MAJ_AXIS_PCNT,(w - 1));
  181.         outpw(MULTIFUNC_CNTL,((h - 1) | MIN_AXIS_PCNT));
  182.         outpw(CMD,command);
  183.         dstp = P_ADDRESS(dst,daddr);
  184.         doff = dst->gc_lineoffset - w;
  185.         while((inpw(GP_STAT) & DATARDY) == 0);
  186.         while(--h >= 0) {
  187.         switch(oper) {
  188.           case C_XOR:
  189.             for(soff = w; --soff >= 0; *dstp++ ^= inpw(PIX_TRANS));
  190.             break;
  191.           case C_OR:
  192.             for(soff = w; --soff >= 0; *dstp++ |= inpw(PIX_TRANS));
  193.             break;
  194.           case C_AND:
  195.             for(soff = w; --soff >= 0; *dstp++ &= inpw(PIX_TRANS));
  196.             break;
  197.           default:
  198.             for(soff = w; --soff >= 0; *dstp++ = inpw(PIX_TRANS));
  199.             break;
  200.         }
  201.         dstp += doff;
  202.         }
  203.         return;
  204.     }
  205.     _GrP8PixCopy(dst,daddr,src,saddr,w,h,op);
  206. }
  207.  
  208.